package com.air.ota.service.imp;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.air.common.util.QueryCondition;
import com.air.common.util.QueryExpression;
import com.air.ota.mo.CancelTrans;
import com.air.ota.mo.DepositTrans;
import com.air.ota.mo.InboundMsg;
import com.air.ota.mo.OutboundMsg;
import com.air.ota.service.ICancelInitHandlerService;
import com.air.ota.service.ICancelTransService;
import com.air.ota.service.ICardPwdService;
import com.air.ota.service.ILastDepositTransHandlerService;
import com.air.ota.service.IOutboundMsgService;
import com.air.ota.service.IPkgSequenceService;
import com.air.ota.util.AppConstant;
import com.air.ota.util.HexStringUtil;
import com.air.ota.util.SZTInterface;
import com.air.ota.vo.SZTBaseResponseVO;
import com.air.ota.vo.SZTCancelInitReqTransVO;
import com.air.ota.vo.SZTCancelInitRequestVO;
import com.air.ota.vo.SZTCancelInitResTransVO;
import com.air.ota.vo.UTKCancelInitDownlinkVO;
import com.air.ota.vo.UTKCancelInitUplinkVO;
import com.air.ota.vo.UTKDepositRequestUplinkVO;

@Service("cancelInitHandlerService")
public class CancelInitHandlerServiceImp implements ICancelInitHandlerService {

	@Autowired
	ICancelTransService cancelTransService;
	@Autowired
	IOutboundMsgService outboundMsgService;
	@Autowired
	IPkgSequenceService pkgSequenceService;
	@Autowired
	ICardPwdService cardPwdService;
	@Autowired
	ILastDepositTransHandlerService lastDepositTransHandlerService;
	
	@Override
	public void process(UTKCancelInitUplinkVO pkgVO, InboundMsg inboundMsg)
			throws Exception {
		System.out.println("------------Ready to Process Cancel Init Request");
		
		CancelTrans duplicateTrans = null;
		if (checkDuplicateTrans(pkgVO, inboundMsg,duplicateTrans)){
			 if ((duplicateTrans.getResult()<0) || (duplicateTrans.getResult()>=AppConstant._cancelResult_init_success)){
				 System.out.println("DISCARD CANCEL INIT MSG,Cause Result="+duplicateTrans.getResult());
				 return;
			 }
		}
		
		lastDepositTransHandlerService.process(pkgVO.getSyncTransDataList(),inboundMsg.getPhoneNumber());
		
		SimpleDateFormat sdf  = new SimpleDateFormat("yyyyMMddHHmmss");
		Date triggerTime = new Date();
		String deviceTriggerTime=sdf.format(triggerTime);
		
		CancelTrans trans = new CancelTrans();
		trans.setSztId("00000000");
		trans.setCellphone(inboundMsg.getPhoneNumber());
		trans.setTransDate(System.currentTimeMillis());
		trans.setCancelSequence(HexStringUtil.bytesToHexString(pkgVO.getCancelSequence()));
		trans.setResult(AppConstant._transResult_processing);
		trans.setCardAppSequence(HexStringUtil.bytesToHexString(pkgVO.getCardAppSequence()));
		trans.setKeyIndex(HexStringUtil.byteToHexString(pkgVO.getKeyIndex()));
		trans.setCardRandom(HexStringUtil.bytesToHexString(pkgVO.getCardRandom()));
		trans.setEwalletTransSequence(HexStringUtil.bytesToHexString(pkgVO.getEwalletTransSequence()));
		trans.setEwalletRemain(HexStringUtil.bytesToHexString(pkgVO.getEwalletRemain()));
		trans.setAmount(HexStringUtil.bytesToHexString(pkgVO.getAmount()));
		trans.setTerminalCode(HexStringUtil.bytesToHexString(pkgVO.getTerminalCode()));
		trans.setLastTransData(HexStringUtil.bytesToHexString(pkgVO.getLastTransData()));
		trans.setCardDeposit(HexStringUtil.bytesToHexString(pkgVO.getCardDeposit()));
		trans.setCardType(HexStringUtil.byteToHexString(pkgVO.getCardType()));
		trans.setDeviceTriggerTime(deviceTriggerTime);
		
		trans = cancelTransService.insertOrUpdate(trans);
		
		boolean pwdAuthResult = cardPwdService.auth(inboundMsg.getPhoneNumber(), pkgVO.getPassword());
		if (!pwdAuthResult){
			System.out.println("password auth failure cellphone="+inboundMsg.getPhoneNumber()+" pwd="+pkgVO.getPassword());
			this.pwdAuthFailureHandler(trans, pkgVO);
			return;
		}
		
		//调用深圳通接口
		byte[] deviceSequence = HexStringUtil.hexStringToBytes(trans.getDeviceSequence());
		byte[] sztSequence = HexStringUtil.hexStringToBytes(trans.getSztId());
		byte[] sumDeviceTransFee = HexStringUtil.hexStringToBytes("00000000");
		byte[] fee = HexStringUtil.hexStringToBytes("00000000");
		
		SZTCancelInitReqTransVO sztCancelInitReqTransVO = new SZTCancelInitReqTransVO(
				deviceSequence,sztSequence,deviceTriggerTime,
				HexStringUtil.hexStringToBytes(trans.getCardAppSequence()),
				HexStringUtil.hexStringToBytes(trans.getCardRandom()),
				HexStringUtil.hexStringToBytes(trans.getEwalletTransSequence()),
				HexStringUtil.hexStringToBytes(trans.getEwalletRemain()),
				HexStringUtil.hexStringToBytes(trans.getAmount()),
				pkgVO.getTransTypeTag(),
				HexStringUtil.hexStringToBytes(trans.getTerminalCode()),
				HexStringUtil.hexStringToBytes(trans.getLastTransData()),
				HexStringUtil.hexStringToBytes(trans.getCardDeposit()),
				fee,
				sumDeviceTransFee
			);
		System.out.println(sztCancelInitReqTransVO.getTransDataHexString());
		SZTCancelInitRequestVO requestVO = new SZTCancelInitRequestVO(sztCancelInitReqTransVO.getTransDataHexString()); 
		SZTInterface sztInterface = new SZTInterface();
		byte[] response=sztInterface.sendRequest(HexStringUtil.hexStringToBytes(requestVO.getMsgPackage()));
		SZTBaseResponseVO responseVO = new SZTBaseResponseVO();
		responseVO.parse(response);
		
		SZTCancelInitResTransVO sztCancelInitResTransVO = new SZTCancelInitResTransVO();
		sztCancelInitResTransVO.parse(HexStringUtil.hexStringToBytes(responseVO.getData()));
		
		//更新CancelTrans对象
		if (sztCancelInitResTransVO.getTransResult()==0x00){//Success
			System.out.println("success");
			trans.setSztId(HexStringUtil.bytesToHexString(sztCancelInitResTransVO.getSztSequence()));
			trans.setMac1(HexStringUtil.bytesToHexString(sztCancelInitResTransVO.getMac1()));
			trans.setOfflineTrans(HexStringUtil.bytesToHexString(sztCancelInitResTransVO.getOfflineTrans()));
			//this.cancelTransService.updateById(trans);
			trans.setResult(AppConstant._cancelResult_init_success);
		}else{
			trans.setResult(AppConstant._cancelResult_init_failure);
			System.out.println("ERROR CODE="+HexStringUtil.byteToHexString(sztCancelInitResTransVO.getTransResult()));
		}
		this.cancelTransService.updateById(trans);
		//Build UTK CancelInit Response Pkg
		
		UTKCancelInitDownlinkVO cancelInitDownlinkVO = new UTKCancelInitDownlinkVO(
				pkgVO.getCardSequence(),pkgSequenceService.getNextSequence(trans.getCellphone()),
				HexStringUtil.hexStringToBytes(trans.getCardAppSequence()),
				HexStringUtil.hexStringToBytes(trans.getCancelSequence()),
				(byte)0x00,
				null,
				HexStringUtil.hexStringToBytes(trans.getDeviceTriggerTime()),
				HexStringUtil.hexStringToBytes(trans.getMac1()),
				HexStringUtil.hexStringToBytes(trans.getOfflineTrans())
		); 
		byte[] responsePkg=cancelInitDownlinkVO.buildPkg();
		cancelInitDownlinkVO.pringCmdDataHexString();
		
		OutboundMsg outboundMsg = new OutboundMsg();
		outboundMsg.setContent(HexStringUtil.bytesToHexString(responsePkg));
		outboundMsg.setDest(0);
		outboundMsg.setPhoneNumber(trans.getCellphone());
		outboundMsg.setSendDate(System.currentTimeMillis());
		outboundMsg.setTransId(trans.getId());
		outboundMsg.setNeedRetry(1);
		outboundMsg.setMsgType(AppConstant._outbound_msg_type_cancelInitResponse);
		outboundMsgService.insert(outboundMsg);
		
	}
	
	private void pwdAuthFailureHandler(CancelTrans trans,UTKCancelInitUplinkVO pkgVO) throws Exception{
		
		trans.setResult(AppConstant._cancelResult_pwdAuth_failure);
		this.cancelTransService.updateById(trans);
		
		String errorDesc="注销失败!密码错误";
		byte[] desc=errorDesc.getBytes("utf-16BE");
		
		UTKCancelInitDownlinkVO cancelInitDownlinkVO = new UTKCancelInitDownlinkVO(
				pkgVO.getCardSequence(),pkgSequenceService.getNextSequence(trans.getCellphone()),
				HexStringUtil.hexStringToBytes(trans.getCardAppSequence()),
				HexStringUtil.hexStringToBytes(trans.getCancelSequence()),
				(byte)0x01,
				desc,
				null,
				null,
				null);
		
		byte[] responsePkg=cancelInitDownlinkVO.buildPkg();
		cancelInitDownlinkVO.pringCmdDataHexString();
		
		OutboundMsg outboundMsg = new OutboundMsg();
		outboundMsg.setContent(HexStringUtil.bytesToHexString(responsePkg));
		outboundMsg.setDest(0);
		outboundMsg.setPhoneNumber(trans.getCellphone());
		outboundMsg.setSendDate(System.currentTimeMillis());
		outboundMsg.setTransId(trans.getId());
		outboundMsg.setNeedRetry(0);
		outboundMsg.setMsgType(AppConstant._outbound_msg_type_cancelInitResponse);
		outboundMsgService.insert(outboundMsg);
	}

	private boolean checkDuplicateTrans(UTKCancelInitUplinkVO pkgVO, InboundMsg inboundMsg,CancelTrans duplicateTrans){
		boolean isDuplicate = false;
		
		QueryCondition condition = new QueryCondition();
		condition.addQueryCondition("cancelSequence",HexStringUtil.bytesToHexString(pkgVO.getCancelSequence()) , QueryExpression.EQUALS);
		condition.addQueryCondition("cellphone",inboundMsg.getPhoneNumber() , QueryExpression.EQUALS);
		List<CancelTrans> queryResult= cancelTransService.queryByCondition(condition);
		
		if (queryResult!=null&&queryResult.size()>0){
			duplicateTrans = queryResult.get(0);
			isDuplicate = true;
		}
		
		return isDuplicate;
	}
	
}
